package app.kernel.locator;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.net.URL;

import kernel.udp.invoke.UDPClient;
import kernel.udp.invoke.XmlRpcClientConfigImpl;
import app.kernel.api.McsAPI;
import app.kernel.connector.config.XmlRpcOutgoingConnection;



// This is use to discover the Addresses of CSG and PSG
public class ComponentsLocator {

	// For Discovering CSM and CSG
	XmlRpcOutgoingConnection myDiscoverer;
	
	public ComponentsLocator() throws Exception{
		
		 myDiscoverer = new XmlRpcOutgoingConnection();
		 
	}

	
	
	// (1) Ask CSM for CSG address.
	// (2) Set up connection with CSG.
	public void Outgoing_CSG_Connection(String CSG_Name) throws Exception{
		
        // Ask CSM for CSG Address
        Object[] params = new Object[]
            { new String(CSG_Name)};
        
        // Retrieve CSG Address from CSM
        String CSG_Address = (String) myDiscoverer.getCSM_Client().execute("CsgManager.get_CSG_Reference", params);
        
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From CSM, get "+CSG_Name+" CSG Address: " +"\nResponse: " +CSG_Address+"");
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Updated CSG references in Cache.");
        
        if (CSG_Address.startsWith("[CSG NOT FOUND]")){        	
        	//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: CSG Not Found! (CSG not registered)");
        }
        else{

        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addCSG_Configuration(CSG_Name, CSG_Address);
        		
        		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+CSG_Name +" CSG.");
        		
        	}
        	catch (Exception e){
        		
        		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: CSG FOUND. CANNOT CONNECT TO CSG.");
        		
        	}
        }
        
	}
	
	
	// (1) Ask CSM for CSG address.
	// (2) Set up connection with CSG.
	public void set_Outgoing_CSG_Connection(String CSG_Name) throws Exception{
		
        // Ask CSM for CSG Address
        Object[] params = new Object[]
            { new String(CSG_Name)};
        
        // Retrieve CSG Address from CSM
        String CSG_Address = (String) myDiscoverer.getCSM_Client().execute("CsgManager.get_CSG_Reference", params);
        
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From CSM, get "+CSG_Name+" CSG Address: " +"\nResponse: " +CSG_Address+"");
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Updated CSG references in Cache.");
        
        if (CSG_Address.startsWith("[CSG NOT FOUND]")){        	
        	//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: CSG Not Found! (CSG not registered)");
        }
        else{

        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addCSG_Configuration(CSG_Name, CSG_Address);
        		
        		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+CSG_Name +" CSG.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: CSG FOUND. CANNOT CONNECT TO CSG.");
        		
        	}
        }
        
	}
	

	
	public void set_Outgoing_CP_Connection_System(String nam, String CSG_Name, String SC_Name, String myIP, int myPort) throws Exception{
		
        
        
		//Retrieve CSG Address from CSM
		String querySignature = "["+myIP+":"+myPort+"]"+"Get Coordinator Peer"+"["+System.currentTimeMillis()+"]";
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"  Query Signature: "+ querySignature);			
		// Add a lookup request so that the API can monitor the returned results.
		((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.addLookupCP_Request(querySignature);            
		
		//System.out.println("[ "+app.io.config.config.resourceName+" ] "+"CSG_Name: "+CSG_Name+"; SCName: "+SC_Name);
        String CP_Address = get_CoordinatorPeer_System(CSG_Name,SC_Name); 
        
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From CSG, get "+CSG_Name+"@"+SC_Name+" CP Address: " +"\nResponse: " +CP_Address+"\n");
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Updated CP references in Cache.\n");
        
        if (CP_Address.startsWith("[SC NOT FOUND]")){   
        	
        	//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC Not Found! (SC not registered)");
        	
        }
        else{

        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addCP_Configuration(CSG_Name+"@"+SC_Name, CP_Address);
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+CSG_Name +" CSG.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC FOUND. CANNOT CONNECT TO CP.");
        		
        	}
        }
        
	}

	// (1) Ask CSG for SemanticCluster's CP address.
	// (2) Set up connection with CP.
	public void set_Outgoing_CP_Connection(String nam, String CSG_Name, String SC_Name, String myIP, int myPort) throws Exception{
		
        
         
		//Retrieve CSG Address from CSM
		String querySignature = "["+myIP+":"+myPort+"]"+"Get Coordinator Peer"+"["+System.currentTimeMillis()+"]";
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"  Query Signature: "+ querySignature);			
		// Add a lookup request so that the API can monitor the returned results.
		((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.addLookupCP_Request(querySignature);            
		
		
        String CP_Address = get_CoordinatorPeer(nam, CSG_Name,SC_Name, myIP, myPort,querySignature); 
        
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From CSG, get "+CSG_Name+"@"+SC_Name+" CP Address: " +"\nResponse: " +CP_Address+"\n");
        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Updated CP references in Cache.\n");
        
        if (CP_Address.startsWith("[SC NOT FOUND]")){   
        	
        //	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC Not Found! (SC not registered)");
        	
        }
        else{

        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addCP_Configuration(CSG_Name+"@"+SC_Name, CP_Address);
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+CSG_Name +" CSG.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC FOUND. CANNOT CONNECT TO CP.");
        		
        	}
        }
        
	}

	
	
	// (1) Ask CP for Random PSG Address
	// (2) Set up connection with assigned PSG.
	public void set_Outgoing_PSG_Connection(String PSG_Address) throws Exception{
		        
        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addPSG_Configuration(PSG_Address, PSG_Address);
        	//	
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+PSG_Address +" PSG.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC FOUND. CANNOT CONNECT TO CP.");
        		
        	}
        
	}
	
	

	// (1) Set up connection with assigned SC_Generator.
	public void set_Outgoing_SC_Gen_Connection(String PSG_Address) throws Exception{
		        
        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addSC_Gen_Configuration(PSG_Address, PSG_Address);
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+PSG_Address +" SC_GEN.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC FOUND. CANNOT CONNECT TO CP.");
        		
        	}
        
	}
		

	// (1) Set up connection with assigned CSG_Generator.
	public void set_Outgoing_CSG_Gen_Connection(String Address) throws Exception{
		        
        	// Establish connection with CSG.
        	try{
        		
        		myDiscoverer.addCSG_Gen_Configuration(Address, Address);
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Application: Connection Established with "+Address +" CSG_GEN.");
        		
        	}
        	catch (Exception e){
        		
        	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC FOUND. CANNOT CONNECT TO CP.");
        		
        	}
        
	}
		
	// Test Connection with CSG
	public void get_Outgoing_CSG_Connection(String CSG_Name) throws Exception{
		
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GET LOCAL CSG CLIENT: ");
		myDiscoverer.getCSG_Client(CSG_Name);
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getCSG_Client(CSG_Name)==null)
			set_Outgoing_CSG_Connection(CSG_Name);
		else{
			// Must be removed next time.
			myDiscoverer.CSG_Configurations.remove(CSG_Name);
			set_Outgoing_CSG_Connection(CSG_Name);
		}
			
		
		//System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Connected to CSG: "+CSG_Name);
	}
	

	
	// Test Connection with CP
	public void get_Outgoing_CP_Connection(String nam, String CSG_Name, String SC_Name, String myIP, int myPort) throws Exception{


		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GET LOCAL CP CLIENT: ");
		myDiscoverer.getCP_Client(CSG_Name+"@"+SC_Name);
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getCP_Client(CSG_Name+"@"+SC_Name)==null)
			set_Outgoing_CP_Connection(nam, CSG_Name, SC_Name, myIP, myPort);
		else{
			
			
			// Must be removed next time.
			myDiscoverer.CP_Configurations.remove(CSG_Name+"@"+SC_Name);
			set_Outgoing_CP_Connection(nam, CSG_Name,SC_Name, myIP, myPort);
			
		}
		System.out.println("[ "+app.io.config.config.resourceName+" ] "+"1. Connected to CP: "+CSG_Name+"@"+SC_Name);
	}

	// Test Connection with CP
	public void get_Outgoing_CP_Connection_System(String nam, String CSG_Name, String SC_Name, String myIP, int myPort) throws Exception{


		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GET LOCAL CP CLIENT: "+myDiscoverer.getCP_Client(CSG_Name+"@"+SC_Name));
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getCP_Client(CSG_Name+"@"+SC_Name)==null)
			set_Outgoing_CP_Connection_System(nam, CSG_Name, SC_Name, myIP, myPort);
		else{
			
			
			// Must be removed next time.
			myDiscoverer.CP_Configurations.remove(CSG_Name+"@"+SC_Name);
			set_Outgoing_CP_Connection_System(nam, CSG_Name,SC_Name, myIP, myPort);
			
		}
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"1. Connected to CP: "+CSG_Name+"@"+SC_Name);
	}

	// Test Connection with PSG
	public void get_Outgoing_PSG_Connection(String PSG_Address) throws Exception{


		
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getPSG_Client(PSG_Address)==null)
			set_Outgoing_PSG_Connection(PSG_Address);
		
		myDiscoverer.getPSG_Client(PSG_Address);
		//System.out.println("[ "+app.io.config.config.resourceName+" ] "+"GET LOCAL PSG CLIENT: "+);
		//System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Connected to PSG: "+PSG_Address);
	}
	

	// Test Connection with SC_Gen
	public void get_Outgoing_SC_Gen_Connection(String PSG_Address) throws Exception{
		
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getSC_Gen_Client(PSG_Address)==null)
			set_Outgoing_SC_Gen_Connection(PSG_Address);
		myDiscoverer.getSC_Gen_Client(PSG_Address);
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GET LOCAL SC_Gen CLIENT: ");
		
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Connected to SC_Gen: "+PSG_Address);
	}

	// Test Connection with SC_Gen
	public void get_Outgoing_CSG_Gen_Connection(String Address) throws Exception{
		
		// If Application does not know the CSG Gateway Address, ask from CSM
		if (myDiscoverer.getCSG_Gen_Client(Address)==null)
			set_Outgoing_CSG_Gen_Connection(Address);
		myDiscoverer.getCSG_Gen_Client(Address);
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GET LOCAL CSG_Gen CLIENT: "+myDiscoverer.getCSG_Gen_Client(Address));
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Connected to CSG_Gen: "+Address);
	}
	
	
	
	public UDPClient get_Sc_Gen_Client_Connection(String SC_Gen_Address) throws Exception{
		
		SC_Gen_Address=SC_Gen_Address.substring(0, SC_Gen_Address.length()-1);
		
	    // create configuration
	    XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(SC_Gen_Address);
	
	    // Create Client
	    UDPClient client = new UDPClient(config);

	    return client;
	}
		
	public String createSC(String CSG_Name, String SCName, String SC_Gen_Address) throws Exception{
		
	    // make the a regular call
	    Object[] params = new Object[]
	        { new String(CSG_Name), new String(SCName)};      
	   // System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Create SC");
		if (!existsSC_Gen(SC_Gen_Address)){
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Get Outgoing SC_Gen Connection!");
			get_Outgoing_SC_Gen_Connection(SC_Gen_Address);
		}	    
	    if (existsSC_Gen(SC_Gen_Address)==false) System.out.println("[ "+app.io.config.config.resourceName+" ] "+"NULL");
	    
	
	    String result1 = "nothing:nothing";
	    try{
	    //	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Is it Null? = "+myDiscoverer.getSC_Gen_Client(SC_Gen_Address));
	        result1 = (String) myDiscoverer.getSC_Gen_Client(SC_Gen_Address).execute("PSG_Manager.createSC", params);
	    }
	    catch (Exception E){
	   // 	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"UhOh");
	    	E.printStackTrace();
	    }
	    
	   // System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Creates SC: " + result1);
	    
	    return result1;		
		
	}	
	
	
public String createCSG(String ParentCSG, String CSG_Name, String CSG_Gen_Address) throws Exception{
		
	    // make the a regular call
	    Object[] params = new Object[]
	        {  new String(CSG_Name)};      
	  //  System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Create CSG");
		if (!existsSC_Gen(CSG_Gen_Address)){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Get Outgoing SC_Gen Connection!");
			get_Outgoing_CSG_Gen_Connection(CSG_Gen_Address);
		}	    
		else System.out.println("[ "+app.io.config.config.resourceName+" ] "+"NULL");
	    
	
	    String result1 = "nothing:nothing";
	    try{
	    	//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Is it Null? = "+myDiscoverer.getCSG_Gen_Client(CSG_Gen_Address));
	        result1 = (String) myDiscoverer.getCSG_Gen_Client(CSG_Gen_Address).execute("CP_Manager.createCSG", params);
	    }
	    catch (Exception E){
	    //	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"UhOh");
	    	E.printStackTrace();
	    }
	    
	//    System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Creates SC: " + result1);
	    
	    return result1;		
		
	}



public String createCSG(String CSG_Name, String CSG_Gen_Address) throws Exception{
		
	    // make the a regular call
	    Object[] params = new Object[]
	        { new String(CSG_Name)};      
	  //  System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Create CSG");
		if (!existsSC_Gen(CSG_Gen_Address)){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Get Outgoing SC_Gen Connection!");
			get_Outgoing_CSG_Gen_Connection(CSG_Gen_Address);
		}	    
		else System.out.println("[ "+app.io.config.config.resourceName+" ] "+"NULL");
	    
	
	    String result1 = "nothing:nothing";
	    try{
	    	//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Is it Null? = "+myDiscoverer.getCSG_Gen_Client(CSG_Gen_Address));
	        System.out.println("Calling CSG Generator");
	    	result1 = (String) myDiscoverer.getCSG_Gen_Client(CSG_Gen_Address).execute("CP_Manager.createCSG", params);
	    	System.out.println(result1);
	    }
	    catch (Exception E){
	    //	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"UhOh");
	    	E.printStackTrace();
	    }
	    
	//    System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Creates SC: " + result1);
	    
	    return result1;		
		
	}	

	//Change made by Shubhabrata

	public void register_PSG_to_CSG(String PSG_ID, String CSG_Name, String IP, int port)
	{
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(PSG_ID), new String(IP), new Integer(port), new String(CSG_Name) };
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	        myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_PSG_to_CSG", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		
	}
	
	//Added  by Shubhabrata
	public void register_PSG_SC_info(String PSG_ID, String CSG_Name, String SCName)
	{
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(PSG_ID), new String(CSG_Name), new String(SCName) };
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	        myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_PSG_SC", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
	}
	
	
	public String register_PSG(String nam, String CSG_Name, String SCName, String RequestorIP, int RequestorPort, String myName){
		
		
		int ch = '?';
		int ch1 = '=';
		int index = myName.indexOf(ch1);
		String temp = myName.substring(index+1, myName.length());
		index = temp.indexOf(ch);
		String PSG_ID = temp.substring(0, index);
		
		String ID = CSG_Name+"@"+SCName;
		String PSG_response = "";
	//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Compo Locate: Reg_PSG: "+ ID);
		
		try{
			
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Checking CSG!");
			String get_CSG_Link = (String) get_CSG_Ref(CSG_Name);
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Get_CSG = "+get_CSG_Link);
			System.out.println("Data from CSG: " + get_CSG_Link);
			if (get_CSG_Link.startsWith("[CSG NOT FOUND]")){
				
				// (1) Get CSG Generator Address from CSM.
	        	String result = get_CSG_Link;
	        	result = result.substring(result.indexOf(":")+1, result.length());
	       // 	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"(1) CSG_Gen = "+result);
			
	        	// (2) Create SC in SC_Generator.
	        	//  -> Foreign call to SC Generator Server
	        	String CSG_Address = createCSG(CSG_Name, result);
	        	String getIPAddress = CSG_Address.substring(0, CSG_Address.indexOf(":"));
	        	String getPort = CSG_Address.substring(CSG_Address.indexOf(":")+1, CSG_Address.length());
	        	System.out.println("CSG Port is " + getPort);
	        	System.out.println("PSG Port is " + RequestorPort);
	        	CSG_Address = "http://"+CSG_Address+"/xmlrpc";
	      // 	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"(2) CSG_Address = "+CSG_Address);	     
	        	
	        	// (3) Helps to Register CSG at CSM.
	        	//  -> Foreign call to CSM Server 
	        	register_CSG(CSG_Name, getIPAddress, Integer.parseInt(getPort));
	        	
	        	String res = CSG_Address;
	        	
				try{
	        		
	        		myDiscoverer.addCSG_Configuration(CSG_Name, res);
	        		
	        //		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+""+CSG_Name+" CSG created.");
	        		
	        	}
	        	catch (Exception e){
	        		e.printStackTrace();
	        //		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: CSG cannot be created.");
	        		
	        	}					        	
	        	
			}
			
			
	//		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Checking SC!");
			//createSC(CSG_Name, SCName, "http://localhost:9081/xmlrpc/");
			
			String querySignature = "["+RequestorIP+":"+RequestorPort+"]"+"Get Coordinator Peer"+"["+System.currentTimeMillis()+"]";
	//		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"  Query Signature: "+ querySignature);			
			// Add a lookup request so that the API can monitor the returned results.
			((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.addLookupCP_Request(querySignature);            
			
			String getS = (String) get_CoordinatorPeer_System(CSG_Name, SCName);
			System.out.println("String getS is: " + getS);
	//		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"GEt_CP = |"+getS+"|");
			// If SC Not found
	        if (getS.startsWith("[SC NOT FOUND]")){
	        	
				// (1) Get SC Generator Address from CSG.
	        	String result = getS;
	    //    	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Result = " + result);
	        	result = result.substring(result.indexOf(":")+1, result.length());
	    //    	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"(1) SC_Gen = "+result);
	        	
	        	// (2) Create SC in SC_Generator.
	        	//  -> Foreign call to SC Generator Server
	        	String SC_Address = createSC(CSG_Name, SCName, result);
	        	String getIPAddress = SC_Address.substring(0,SC_Address.indexOf(":"));
	        	String getPort = SC_Address.substring(SC_Address.indexOf(":")+1, SC_Address.length());
	        	SC_Address = "http://"+SC_Address+"/xmlrpc";
	 //       	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"(2) SC_Address = "+SC_Address);
	        	
	        	// (3) Helps to Register SC at CSG.
	        	//  -> Foreign call to CSG Server 
	        	
	        	//This is where the new coordinator peer is assigned. Possible changes required here
	        	System.out.println("Before register_CP IP is: " + RequestorIP);
	        	register_CP(CSG_Name, SCName, getIPAddress, Integer.parseInt(getPort));
	        	
	        	
/*		        Object[] params2 = new Object[]
		                     	            { new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort), new Boolean(true) };
		        
		        System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"1");
				String res = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_PSG",params2);
		        System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"2");				
				res = "http://"+res+"/xmlrpc";
				System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"res = "+res);
	*/			

	        	String res = SC_Address;
	        	
				try{
	        		
	        		myDiscoverer.addCP_Configuration(CSG_Name+"@"+SCName, res);
	        		
	   //     		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+""+CSG_Name+"@" +SCName +" CP created.");
	        		
	        	}
	        	catch (Exception e){
	        		e.printStackTrace();
	        //		System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: SC cannot be added.");
	  //      		
	        	}				
				
			}
	        
	        //Changes made for the purpose of improving reliability - Shubhabrata
	        
	        register_PSG_Info(RequestorIP, Integer.toString(RequestorPort), CSG_Name, SCName, PSG_ID);
	        
	        //Change made by Shubhabrata - Register PSG information to the CSG for use in tracking
	        
	        register_PSG_to_CSG(PSG_ID,CSG_Name, RequestorIP, RequestorPort );
	        
	        /*Change made by Shubhabrata - Register the information about each PSG and the semantic clusters
	         * associated with it*/
	        
	  	    register_PSG_SC_info(PSG_ID, CSG_Name, SCName);
	        
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"My Name = "+myName);
	        // Make a regular call
	        /* Check whether the clustering algorithm needs to be invoked by checking for the numeric data type. If yes, invoke and determine the
	         * cluster to join and pass this while registering the PSG*/
	        Object[] params = new Object[]
	                     	            { new String(CSG_Name), new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort), new String(myName) };
	        PSG_response = (String) myDiscoverer.getCP_Client(ID).execute("PSG_Manager.register_PSG", params);

		    
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg PSG response: "+"\nResponse: " + PSG_response+"\n");
			
	        return PSG_response;
		}
		catch (Exception e){
			e.printStackTrace();
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register PSG1");
		    return "";
		}
		
	}
	

	public String register_PSG(String ParentCSG, String nam, String CSG_Name, String SCName, String RequestorIP, int RequestorPort, String myName){
		
		String ID = CSG_Name+"@"+SCName;
		String PSG_response = "";
		System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Compo Locate: PARENT Reg_PSG: "+ ID);
		System.out.println("[ "+app.io.config.config.resourceName+" ] "+ParentCSG+"; "+CSG_Name);
		try{
			
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Checking CSG!");
			String get_CSG_Link = (String) get_CSG_Ref(CSG_Name);
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Get_CSG = "+get_CSG_Link);
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			/// - CODES TO ADD HERE!!
			if (get_CSG_Link.startsWith("[CSG NOT FOUND]")){
				
				// (1) Get CSG Generator Address from CSM.
	        	String result = get_CSG_Link;
	        	result = result.substring(result.indexOf(":")+1, result.length());
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"(1) CSG_Gen = "+result);
			
	        	// (2) Create SC in SC_Generator.
	        	//  -> Foreign call to SC Generator Server
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"CREATING PARENT CHILD CSG");
	        	String CSG_Address = createCSG(ParentCSG, CSG_Name, result);
	        	String getIPAddress = CSG_Address.substring(0, CSG_Address.indexOf(":"));
	        	String getPort = CSG_Address.substring(CSG_Address.indexOf(":")+1, CSG_Address.length());
	        	CSG_Address = "http://"+CSG_Address+"/xmlrpc";
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"(2) CSG_Address = "+CSG_Address);	     
	        	
	        	// (3) Helps to Register CSG at CSM.
	        	//  -> Foreign call to CSM Server 
	        	register_CSG(ParentCSG, CSG_Name, getIPAddress, Integer.parseInt(getPort));
	        	
	        	String res = CSG_Address;
	        	
				try{
	        		
	        		myDiscoverer.addCSG_Configuration(CSG_Name, res);
	        		
	        		System.out.println("[ "+app.io.config.config.resourceName+" ] "+""+CSG_Name+" CSG created.");
	        		
	        	}
	        	catch (Exception e){
	        		e.printStackTrace();
	        		System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: CSG cannot be created.");
	        		
	        	}					        	
	        	
			}
			
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Checking SC!");
			//createSC(CSG_Name, SCName, "http://localhost:9081/xmlrpc/");
			
			String querySignature = "["+RequestorIP+":"+RequestorPort+"]"+"Get Coordinator Peer"+"["+System.currentTimeMillis()+"]";
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  Query Signature: "+ querySignature);			
			// Add a lookup request so that the API can monitor the returned results.
			((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.addLookupCP_Request(querySignature);            
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"GET CootdinatorPeerSys: "+CSG_Name+"."+SCName);
			String getS = (String) get_CoordinatorPeer_System(CSG_Name, SCName);
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"GEt_CP = |"+getS+"|");
			// If SC Not found
	        if (getS.startsWith("[SC NOT FOUND]")){
	        	
				// (1) Get SC Generator Address from CSG.
	        	String result = getS;
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Result = " + result);
	        	result = result.substring(result.indexOf(":")+1, result.length());
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"(1) SC_Gen = "+result);
	        	
	        	// (2) Create SC in SC_Generator.
	        	//  -> Foreign call to SC Generator Server
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
	        	String SC_Address = createSC(CSG_Name, SCName, result);
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"-----> "+CSG_Name+"."+ SCName+" = " +result);
	        	String getIPAddress = SC_Address.substring(0,SC_Address.indexOf(":"));
	        	String getPort = SC_Address.substring(SC_Address.indexOf(":")+1, SC_Address.length());
	        	SC_Address = "http://"+SC_Address+"/xmlrpc";
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"(2) SC_Address = "+SC_Address);
	        	
	        	// (3) Helps to Register SC at CSG.
	        	//  -> Foreign call to CSG Server 
	        	System.out.println("[ "+app.io.config.config.resourceName+" ] "+CSG_Name+"; "+ SCName+"; "+ getIPAddress+":"+ Integer.parseInt(getPort));
	        	register_CP(CSG_Name, SCName, getIPAddress, Integer.parseInt(getPort));
	        	
	        	
/*		        Object[] params2 = new Object[]
		                     	            { new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort), new Boolean(true) };
		        
		        System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"1");
				String res = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_PSG",params2);
		        System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"2");				
				res = "http://"+res+"/xmlrpc";
				System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"res = "+res);
	*/			

	        	String res = SC_Address;
	        	
				try{
	        		
	        		myDiscoverer.addCP_Configuration(CSG_Name+"@"+SCName, res);
	        		
	        		System.out.println("[ "+app.io.config.config.resourceName+" ] "+""+CSG_Name+"@" +SCName +" CP created.");
	        		
	        	}
	        	catch (Exception e){
	        		e.printStackTrace();
	        		System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: SC cannot be added.");
	        		
	        	}				
				
			}
	        
	        
	      //  System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"My Name = "+myName);
	        // Make a regular call
	        Object[] params = new Object[]
	                     	            { new String(CSG_Name), new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort), new String(myName) };
	        PSG_response = (String) myDiscoverer.getCP_Client(ID).execute("PSG_Manager.register_PSG", params);

		    
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg PSG response: "+"\nResponse: " + PSG_response+"\n");
			return PSG_response;
		}
		catch (Exception e){
			e.printStackTrace();
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: Cannot register PSG1");
		    return "";
		}
		
	}
		
	
	
	public void register_CP(String CSG_Name, String SCName, String RequestorIP, int RequestorPort){


		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(CSG_Name), new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort) };
	        
		    String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
		    
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		
	}
	
	public void register_PSG_Info(String IP, String Port, String CSG_Name, String SCName, String PSG_ID)
	{
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(IP), new String(Port), new String(CSG_Name),new String(SCName), new String(PSG_ID) };
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	        myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_PSG_CP", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
	}

	
	// Remote method in CSM
	public String register_CSG(String CSG_Name, String requestorIP, int requestorPort) throws Exception{
		
	    // make the a regular call
	    Object[] params = new Object[]
	        { new String(CSG_Name), new String(requestorIP), new Integer(requestorPort) };        
	    String result1 = (String) myDiscoverer.getCSM_Client().execute("CsgManager.register_CSG", params);
	    //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Register CSG: " + result1);
	    
	    return result1;
	}

	// Remote method in CSM
	public String register_CSG(String ParentCSG, String CSG_Name, String requestorIP, int requestorPort) throws Exception{
		
	    // make the a regular call
	    Object[] params = new Object[]
	        { new String(ParentCSG), new String(CSG_Name), new String(requestorIP), new Integer(requestorPort) };
	    System.out.println("[ "+app.io.config.config.resourceName+" ] "+ParentCSG+"; "+CSG_Name + "; "+ requestorIP+":"+requestorPort);
	    String result1 = (String) myDiscoverer.getCSM_Client().execute("CsgManager.register_CSG", params);
	    System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Register PARENT CSG: " + result1);
	    
	    return result1;
	}


	
	public void register_SC_Gen(String CSG_Name, String RequestorIP, int RequestorPort){


		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(RequestorIP+":"+(RequestorPort))};
	        
		    String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("SC_Gen_Manager.register_SC_Gen", params);
		    
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg SC_Gen response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register SC_Gen");
		}
		
	}
			
	//Added by Shubhabrata - Get session id
	
	public String getSessionId(String name, String CSG, String IPPort)
	{
		String id = "NULL";
		
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(name), new String(CSG), new String(IPPort)};
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	         id = (String)myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.getSessionId", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		return id;
	}
	public void deleteSessionId(String name, String MSID)
	{
		String id = "NULL";
		String CSG = MSID.substring(0, MSID.indexOf("@"));
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(name), new String(CSG), new String(MSID)};
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	         myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.deleteSessionId", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		//return id;
	}
	
	//Added by Shubhabrata - Register the callback session
	
	public String registerCallback(String callerId, String calleeId)
	{
		String response = "NULL";
		
		//here we need to extract callee CSG
//		System.out.println("Received callee and caller: "+calleeId+" "+callerId);
		String callerMSID = callerId.substring((callerId.indexOf(":")+1), callerId.length());
		String CSG = callerMSID.substring(0, callerMSID.indexOf("@"));
//		CSG = "person";
		/*
		 * Get CSG name from the calleeID (MSID + ASID). Also check whether both the caller and
		 * callee MSID are valid by checking the middleware (which will be verified inside CP_Manager.java)
		 */
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(CSG), new String(callerId), new String(calleeId)};
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	         response = (String)myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.registerCallback", params);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		return response;
		
	}
	//Ivan 23 June 2010
	public String withdrawCallback(String callerId, String calleeId){
		String response = "NULL";
		//extract callee CSG
		String callerMSID = callerId.substring(callerId.indexOf(":")+1);
		String CSG = callerMSID.substring(0, callerMSID.indexOf("@"));
		try {
			Object[] params = new Object[] {
					 new String(callerId),new String(calleeId)
			};
			
			response = (String)myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.withdrawCallback", params);
		}catch(Exception e){
			
		}
		return response;
	}
	public String getIPPort(String MSID){
		String response = "NULL";
		//extract callee CSG
//		String callerMSID = callerId.substring(callerId.indexOf(":")+1);
		String CSG = MSID.substring(0, MSID.indexOf("@"));
		try {
			Object[] params = new Object[] {
					 new String(MSID)//,new String(calleeId)
			};
			
			response = (String)myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.getIPPort", params);
		}catch(Exception e){
			
		}
		return response;
	}
	//Added by Shubhabrata
	public String mobilityUpdate(String nam, String sessionId, String IPPort)
	{
		String response = "NULL";
		String CSG = sessionId.substring(0, sessionId.indexOf("@"));
		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(nam), new String(CSG), new String(sessionId),new String(IPPort)};
	        
		    //String PSG_response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.register_CP", params);
	        long beginOne = System.currentTimeMillis(); 
	        response = (String)myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.mobilityUpdate", params);
	        long endOne = System.currentTimeMillis();
	        long mobilityUpdatingTime = endOne - beginOne;
	        System.out.println("[Server handling mobility updating time]: "+mobilityUpdatingTime);
	        writeLog("mobilityServerTime",""+mobilityUpdatingTime);
	         //mobility updating will activate the notification generation process
	        long beginTwo = System.currentTimeMillis();
	         myDiscoverer.getCSG_Client(CSG).execute("CP_Manager.callbackNotification", params);
	        long endTwo = System.currentTimeMillis();
	        long callbackServerTime = endTwo - beginTwo;
	        System.out.println("[Server handling callback service]: "+callbackServerTime);
	        writeLog("callbackServerTime",""+callbackServerTime);
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		return response;
		
	}

	public String leave_PSG(String ValueType, String Value, String CSG_Name, String SCName, String RequestorIP, int RequestorPort){
		
		String ID = CSG_Name+"@"+SCName;
		String PSG_response = "";
		try{
			// May change back
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(ValueType),new String(Value),new String(CSG_Name), new String(SCName),  new String(RequestorIP),  new Integer(RequestorPort) };
	        
	    //    System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Leave_PSG: "+CSG_Name+"@"+SCName+" -> "+ RequestorIP+":"+RequestorPort);
	        PSG_response = (String) myDiscoverer.getCP_Client(ID).execute("PSG_Manager.leave_PSG", params);

		    
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get leave PSG response: "+"\nResponse: " + PSG_response+"\n");
			return PSG_response;
		}
		catch (Exception e){
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: Cannot leave PSG1");
		    return "";
		}
		
	}
		

	// Initiate Connection with neighbour
	public void register_Neighbor(String CSG_Name, String SCName, String nam, String destinatedAddress, String RequestorAddress){


		try{
	        // Make a regular call
	        Object[] params = new Object[]
	            { new String(CSG_Name),new String(SCName),new String(nam), new String(RequestorAddress) };	        
		    String PSG_response = (String) myDiscoverer.getPSG_Client(destinatedAddress).execute("RequestsManager.registerNeighbour", params);		    
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+RequestorAddress+" PSG, get reg PSG response: "+"\nResponse: " + PSG_response+"\n");		
		}
		catch (Exception e){
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Cannot register CP");
		}
		
	}
	
	public String get_CSG_Ref(String CSG_Name){
		
		String response="ERROR: Get_Coordinator Peer\n";
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(CSG_Name)};  
	        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"<Get Coordinator Peer>");
            response = (String) myDiscoverer.getCSM_Client().execute("CsgManager.get_CSG_Reference", params3);        
            //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From CSM, get reg CSG of "+CSG_Name+" response: "+"\nResponse: " + response+"\n");
	        //System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"</Get Coordinator Peer>");
            
            
		}
		catch (Exception e){
			//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Get_Coordinator Peer");
		}
		return response;
		
		
	}

	
	public String get_CoordinatorPeer_System(String CSG_Name, String SCName) throws Exception{
		
		
		String response="ERROR: Get_Coordinator Peer\n";
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(CSG_Name), new String(SCName)};  
      //      System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"<Get Coordinator Peer System Side>");
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"GCPS --------> "+CSG_Name+"  @ "+SCName);
            response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.get_CoordinatorPeer_System", params3);        
      //      System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP of "+SCName+"@"+CSG_Name+" response: "+"\nResponse: " + response+"\n");
	//        System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"</Get Coordinator Peer System Side>");
            return response;
		}
		catch (Exception e){
		//	System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Get_Coordinator Peer");
			return "[SC NOT FOUND]";
		}
		
		
	}
	
	
	public String get_CoordinatorPeer(String nam, String CSG_Name, String SCName, String myIP, int listeningPort, String qSignature){
		
		
		String response="ERROR: Get_Coordinator Peer\n";
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(CSG_Name), new String(SCName), new String(myIP), new Integer(listeningPort), new String(qSignature)};  
	   //     System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"<Get Coordinator Peer>");
            response = (String) myDiscoverer.getCSG_Client(CSG_Name).execute("CP_Manager.get_CoordinatorPeer", params3);        
      //      System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+CSG_Name+" CSG, get reg CP of "+SCName+"@"+CSG_Name+" response: "+"\nResponse: " + response+"\n");
	   //     System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"</Get Coordinator Peer>");

	        String result = response;
        	result = result.substring(result.indexOf(":")+1, result.length());
				
	        
	        if (response.startsWith("ROUTING QUERY THROUGH RING")){
	        	
				int i=0;
				int maxT = config.PSG_Configuration.TimeOutForQuery/20;
				while ((((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.getCPResults(qSignature).Size()==0) &&(i<maxT)){
					
					Thread.currentThread().sleep(20);
					i++;			
				}
				if (i==maxT) return "[SC NOT FOUND]:"+result;
				
				return (String)((McsAPI)app.demo.demo.PSGs.get(nam)).myRequests.getCPResults(qSignature).getResults().get(0);
	        	
	        }
	        else // Most Likely won't reach here
	        	return "[SC NOT FOUND]:"+ result;
	        

            
		}
		catch (Exception e){
		//System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: Get_Coordinator Peer");
			return "[SC NOT FOUND]";
		}
		
		
	}
	
    public boolean existsCP(String CSG_Name, String SCName){
		
		return myDiscoverer.existsCP(CSG_Name, SCName);
		
	}

    // Exists CSG_Gen.
    public boolean existsCSG_Gen(String Address){
		
		return myDiscoverer.existsCSG_Gen(Address);
		
	}

    // Exists SC_Gen.
    public boolean existsSC_Gen(String SC_Gen_Address){
		
		return myDiscoverer.existsSC_Gen(SC_Gen_Address);
		
	}

    public boolean existsPSG(String PSG_Address){
		
		return myDiscoverer.existsPSG(PSG_Address);
		
	}
    /*
    // Disseminate Query to assigned PSG in a Semantic Cluster.
    public String queryPSG(String destinationAddress, String QueryString, String listeningPortAddress){
    	
		String response="Error: QueryPSG";
		String ID = destinationAddress;
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(QueryString)};        
            response = (String) myDiscoverer.getPSG_Client(ID).execute("QueryP2P.queryPSG", params3);
            System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"PSG ID: "+ID);
            System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Request : From "+listeningPortAddress+" PSG, get reg CP of "+ID+" response: "+"\nResponse: " + response+"\n");	
		}
		catch (Exception e){
			System.out.println("[ "+kernel.udp.config.config.resourceName+" ] "+"Error: QueryPSG");
		}
		finally{			
			  return response;
		}
		  
    	//return "";
    	
    }
    */
    // Disseminate Query to assigned PSG in a Semantic Cluster.
    public String foreignQueryP2P(String CSG_Name, String SCName,String nam, String signature, String destinationAddress, String QueryString, String listeningPortAddress) throws Exception{
    	
		String response="Error: QueryP2P 1";
		String ID = destinationAddress;
		
		
		try{
			//System.out.println("[ "+app.io.config.config.resourceName+" ] "+"\n<Components Locator Start - foreignQueryP2P>");
			// Make a regular call
	        Object[] params3 = new Object[]
                   {new String(CSG_Name), new String (SCName), new String(ID), new String(signature),new String(QueryString),new String(listeningPortAddress)};
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  <signature> "+signature+" </signature>");
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  <destination> ["+destinationAddress+"] </destination>");
			if (!existsPSG(ID)){
				get_Outgoing_PSG_Connection(ID);				
			}	
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"   <Testing> Get Client connection: "+myDiscoverer.getPSG_Client(ID)+" </Testing>");
	        
            response = (String) myDiscoverer.getPSG_Client(ID).execute("RequestsManager.queryP2P", params3);
	        //response = (String) myDiscoverer.getPSG_Client(ID).execute("RequestsManager.testcase1", params3);
	        	        
	        //response = myDiscoverer.getPSG_Client(ID).toString();
	        
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+response);
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"</Components Locator End>\n");
            //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Request : From "+listeningPortAddress+" PSG, get reg CP of "+ID+" response: "+"\nResponse: " + response+"\n");	
		}
		catch (Exception e){
			e.printStackTrace();
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: QueryP2P 2");
		}
		finally{			
			  return response;
		}
		  
    	//return "";
    	
    }
    // Disseminate Query to assigned PSG in a Semantic Cluster.
    public String foreignQueryP2P(String CSG_Name, String SCName, String nam, String signature, String destinationAddress, String QueryString, String listeningPortAddress, int TTL) throws Exception{
    	
		String response="Error: QueryP2P 1";
		String ID = destinationAddress;
		
		
		try{
		//	System.out.println("[ "+app.io.config.config.resourceName+" ] "+"\n<Components Locator Start - foreignQueryP2P>");
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(CSG_Name), new String (SCName), new String(destinationAddress), new String(signature),new String(QueryString),new String(listeningPortAddress), new Integer(TTL)};
	       // System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  <signature> "+signature+" </signature>");
	       // System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  <destination> ["+destinationAddress+"] </destination>");
			if (!existsPSG(ID)){
				get_Outgoing_PSG_Connection(ID);				
			}	
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"   <Testing> Get Client connection: "+myDiscoverer.getPSG_Client(ID)+" </Testing>");
            response = (String) myDiscoverer.getPSG_Client(ID).execute("RequestsManager.queryP2P", params3);
	        //response = (String) myDiscoverer.getPSG_Client(ID).execute("RequestsManager.testcase1", params3);
	        	        
	        //response = myDiscoverer.getPSG_Client(ID).toString();
	        
	       // System.out.println("[ "+app.io.config.config.resourceName+" ] "+response);
	       // System.out.println("[ "+app.io.config.config.resourceName+" ] "+"</Components Locator End>\n");
           // System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Request : From "+listeningPortAddress+" PSG, get reg CP of "+ID+" response: "+"\nResponse: " + response+"\n");	
		}
		catch (Exception e){
			e.printStackTrace();
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: QueryP2P 2");
		}
		finally{			
			  return response;
		}
		  
    	//return "";
    	
    }
        
    // Support RDF Query Currently, Find and Contact CP
	public String queryMCS(String CSG_Name, String SCName, String QueryString, String requestorAddress){

		String response="Error: QueryMCS 2";
		String ID = CSG_Name+"@"+SCName;
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   {new String(CSG_Name), new String(SCName),  new String(QueryString),new String(requestorAddress)};
	        System.out.println("[ "+app.io.config.config.resourceName+" ] "+"\n<Remote QueryMCS Call Request>");
            response = (String) myDiscoverer.getCP_Client(ID).execute("PSG_Manager.queryMCS", params3);        
            System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  Request : From "+CSG_Name+" CSG, get reg CP "+ID+" response: "+"\n  Response: " + response+"\n");	
	        System.out.println("[ "+app.io.config.config.resourceName+" ] "+"</Remote QueryMCS Call Request>\n");
		}
		catch (Exception e){
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: QueryMCS 1");
		}
		finally{
			  return response;
		}
		  
		
	}
    // Support RDF Query Currently, Find and Contact CP
	public String reportResults(String nam, String destination, String Result, String querySignature, String requestorAddress){

		String response="Error: Report Results 2";
		String ID = destination;
		try{
			// Make a regular call
	        Object[] params3 = new Object[]
                   { new String(nam),new String(destination), new String(Result),new String(querySignature)};
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"\n<Remote Report Results Call Request>");
            response = (String) myDiscoverer.getPSG_Client(ID).execute("RequestsManager.registerResult", params3);        
            //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"  Request : From "+requestorAddress+" PSG, report results to PSG "+ID+" response: "+"\n  Response: " + response+"\n");	
	        //System.out.println("[ "+app.io.config.config.resourceName+" ] "+"</Remote Report Results Call Request>\n");
		}
		catch (Exception e){
			System.out.println("[ "+app.io.config.config.resourceName+" ] "+"Error: Report Results 1");
		}
		finally{
			  return response;
		}
		  
		
	}
	
	// write data to file
	public static void writeLog(String fileName, String content)
    {
            try{
                FileWriter fstream = new FileWriter("D:\\Person\\"+fileName+".txt",true);
                BufferedWriter out = new BufferedWriter(fstream);
                out.write(content);
                out.write(System.getProperty( "line.separator" ));
                out.write(System.getProperty( "line.separator" ));
                //Close the output stream
                out.close();
                }
            catch (Exception e){//Catch exception if any
             System.err.println("Error: " + e.getMessage());}
    }
	
	
			
	
}
